#include <gtest/gtest.h>
#include "tinyxml2/tinyxml2.h"

static const char *XML_STR = R"(
<?xml version="1.0"?>
<launch>
    <node pkg="nodelet" type="nodelet" name="nodelet_manager" args="manager" output="screen">
        <param name="num_worker_threads" value="15"/>
    </node>
    <include file="$(find lds_driver)/launch/ld14p.launch" />
    <include file="$(find oss_manager)/launch/oss_server_manage.launch" />
</launch>
)";

//转成xml字符串打印
void printXML(tinyxml2::XMLElement *element)
{
    tinyxml2::XMLPrinter printer;
    element->Accept(&printer);
    printf("%s\n", printer.CStr());
}

TEST(test_tinyxml2, test_tinyxml2_parser)
{
    tinyxml2::XMLDocument document;
    tinyxml2::XMLError error = document.Parse(XML_STR);
    if (tinyxml2::XMLError::XML_SUCCESS != error)
    {
        FAIL();
    }
    tinyxml2::XMLElement *element = document.FirstChildElement("launch");
    printf("%s\n", element->Name());//launch

    tinyxml2::XMLElement *pElement = element->FirstChildElement("node");
    printf("%s\n", pElement->Name());//node
    printXML(pElement);

    const char *pkg;
    pElement->QueryAttribute("pkg", &pkg);
    printf("%s\n", pkg);//nodelet
}

TEST(test_tinyxml2, test_tinyxml2_traverse)
{
    tinyxml2::XMLDocument document;
    tinyxml2::XMLError error = document.Parse(XML_STR);
    if (tinyxml2::XMLError::XML_SUCCESS != error)
    {
        FAIL();
    }
    tinyxml2::XMLElement *element = document.FirstChildElement("launch");
    printf("%s\n", element->Name());//launch

    tinyxml2::XMLElement *childElement = element->FirstChildElement();
    if (nullptr == childElement)
    {
        return;
    }
    printf("%s\n", childElement->Name());//node
    do
    {
        childElement = childElement->NextSiblingElement();
        if (nullptr == childElement)
        {
            break;
        }
        printf("%s\n", childElement->Name());
    }
    while (true);
}
TEST(test_tinyxml2, test_tinyxml2_sample)
{
    static const char *xml = R"(
        <?xml version="1.0"?>
        <!DOCTYPE PLAY SYSTEM "play.dtd">
        <PLAY>
            <TITLE>A Midsummer Night's Dream</TITLE>
        </PLAY>"
    )";

    tinyxml2::XMLDocument doc;
    doc.Parse(xml);

    tinyxml2::XMLElement *titleElement = doc.FirstChildElement("PLAY")->FirstChildElement("TITLE");
    const char *title = titleElement->GetText();
    printf("Name of play (1): %s\n", title);

    tinyxml2::XMLText *textNode = titleElement->FirstChild()->ToText();
    title = textNode->Value();
    printf("Name of play (2): %s\n", title);
}
TEST(test_tinyxml2, test_tinyxml2_sample2)
{
    static const char *xml =
        "<information>"
        "	<attributeApproach v='2' />"
        "	<textApproach>"
        "		<v>2</v>"
        "	</textApproach>"
        "</information>";

    tinyxml2::XMLDocument doc;
    doc.Parse(xml);

    int v0 = 0;
    int v1 = 0;

    tinyxml2::XMLElement *attributeApproachElement = doc.FirstChildElement()->FirstChildElement("attributeApproach");
    attributeApproachElement->QueryIntAttribute("v", &v0);

    tinyxml2::XMLElement *textApproachElement = doc.FirstChildElement()->FirstChildElement("textApproach");
    textApproachElement->FirstChildElement("v")->QueryIntText(&v1);

    printf("Both values are the same: %d and %d\n", v0, v1);
}
